luachipTransfer = {}
lcTrans = luachipTransfer
local ws = luachipTransfer

local stack = {}

ws.cmd = {}

function ws.ccTran(pl,cmd,args)
	local dat = args[1]
	if type(dat) ~= "string" then
		return
	end
	
	if cmd == "lc" then //Data transfer
		if stack[pl] then
			Msg("WS: RECV ",pl," DAT ",dat,"\n")
			table.insert(stack[pl].dat,dat)
		end
	elseif cmd == "lci" then //Interrupt
		if dat == "open" then
			local num = tonumber(args[2]) or nil
			Msg("WS: OPEN ",pl," QTY ",num,"\n")
			
			stack[pl] = {
				dat = {},
				qty = num,
			}
		elseif dat == "close" then
			local cmd = tostring(args[2]) or "nil"
			
			Msg("WS: CLOSE ",pl," CMD ",cmd,"\n")
			
			if stack[pl] then
				local out = ""
				for k,v in pairs(stack[pl].dat) do
					out = out..v
				end
				out = out:gsub(",.:nl:.,","\n")
				
				Msg(out,"\n")
				if ws.cmd[cmd] then
					ws.cmd[cmd](pl,out)
				end
				
				stack[pl] = nil
			end
		elseif dat == "download" then
			//WARNING: This is an entity implementation
			if not luachip.plent then
				return
			end
			
			local ent = luachip.plent[pl]
			if not luachip.playerAccess(pl,ent) then
				return
			end
			ws.sendstack[pl] = {
				open = false,
				dat = tostring(ent.luachipCode or ""),
			}
		end
	end
end

function ws.setCommandFunction(command,f)
	ws.cmd[command] = f
end

concommand.Add("lc",ws.ccTran)
concommand.Add("lci",ws.ccTran)


ws.sendstack = {}
ws.tickrate = 20 //Ticks per second
ws.packetsize = 230 //Bytes per packet
ws.nextSend = CurTime()+1/ws.tickrate
ws.sendThink = function()
	if ws.nextSend < CurTime() then
		for pl,dat in pairs(ws.sendstack) do
			if dat.open then
				if dat.stack[dat.next] then
					//Send
					umsg.Start("lc",pl)
						umsg.String(dat.stack[dat.next])
					umsg.End()
					dat.next = dat.next+1
				elseif dat.next > dat.qty then
					//Close
					umsg.Start("lci",pl)
						umsg.Char(2)
						umsg.String("luachipswep")
					umsg.End()
					ws.sendstack[pl] = nil
				end
			else
				//Break up the data
				dat.stack = {}
				
				dat.dat = dat.dat:gsub("\n",",.:nl:.,")
				
				for i = 1,#dat.dat,ws.packetsize do
					table.insert(dat.stack,dat.dat:sub(1,ws.packetsize))
					dat.dat = dat.dat:sub(ws.packetsize+1)
				end
				
				PrintTable(dat.stack)
				dat.qty = #dat.stack
				dat.next = 1
				dat.open = true
				
				umsg.Start("lci",pl)
					umsg.Char(1)
					umsg.Long(dat.qty)
					umsg.Short(ws.tickrate)
				umsg.End()
			end
		end
		ws.nextSend = CurTime()+1/ws.tickrate
	end
end

hook.Add("Think","luachipTransfer.sendThink",ws.sendThink)
















